package com.cleargroup.magic.cleara.c.command;

import android.content.Context;
import android.os.Build;

import com.cleargroup.magic.cleara.c.BatteryHelper;

import java.io.File;
import java.util.ArrayList;
import java.util.List;


public class ScanManage {
	private static final String TAG = ScanManage.class.getSimpleName();
	private final static String TIME_LIMIT = "time_limit";
	private static ScanManage instance;
	private ScanManageListener listener;
	private Scan scan;

	private List<String> trashList;
	public  long         trashTotalSize;
	public  long         thumbTotalSize;
	public  long         apkTotalSize;
	private List<String> apkList;
	private List<String> thumbList;
	private List<String> emptyList;
	private List<String> largeFileList;
	private Context context;

	private ScanListener mScanListener = new ScanListener() {
		@Override
		public void onNodeScan(File node) {
			int type = TrashHelper.detect(node);

			if (type == TrashHelper.TRASH_APK) {
				apkList.add(node.getAbsolutePath());
				apkTotalSize += node.length();
			}

			else if (type == TrashHelper.TRASH_THUMBNAIL) {
				thumbList.add(node.getAbsolutePath());
				thumbTotalSize += node.length();
			}

			else if (type == TrashHelper.TRASH_TEMPERARY
					|| type == TrashHelper.TRASH_LOGFILE
					|| type == TrashHelper.TRASH_INVALID) {
				trashList.add(node.getAbsolutePath());
			}

			else if (type == TrashHelper.TRASH_EMPTY) {
				emptyList.add(node.getAbsolutePath());
			}

			else if (type == TrashHelper.TRASH_LARGEFILE) {
				largeFileList.add(node.getAbsolutePath());
			}

			if (getListener() != null) {
				getListener().onNodeScan(type, node);
			}
		}
	};

	private ScanManage(Context context) {
		this.context = context;
		this.trashList = new ArrayList<String>();
		this.apkList = new ArrayList<String>();
		this.thumbList = new ArrayList<String>();
		this.emptyList = new ArrayList<String>();
		this.largeFileList = new ArrayList<String>();
	}

	public static ScanManage getInstance(Context context) {
		if (instance == null) {
			instance = new ScanManage(context);
		}
		return instance;
	}

	public void scanTrash(String path, ScanManageListener listener) {
		if (isTimeUp() || !isScanComplete()) {
			scanFullPath(path, listener);
		} else {
			traverseTrashList(listener);
		}
	}

	private void traverseTrashList(ScanManageListener listener) {
		setListener(listener);
		for (int i = 0; i < trashList.size() && getListener() != null; i++) {
			File node = new File(trashList.get(i));
			getListener().onNodeScan(TrashHelper.TRASH_TEMPERARY, node);
		}
	}

	public void scanApk(String path, ScanManageListener listener) {
		if (isTimeUp() || !isScanComplete()) {
			scanFullPath(path, listener);
		} else {
			traverseApkList(listener);
		}
	}

	private void traverseApkList(ScanManageListener listener) {
		setListener(listener);

		for (int i = 0; i < apkList.size() && getListener() != null; i++) {
			File node = new File(apkList.get(i));
			getListener().onNodeScan(TrashHelper.TRASH_APK, node);
		}
	}

	public void scanThumb(String path, ScanManageListener listener) {
		if (isTimeUp() || !isScanComplete()) {
			scanFullPath(path, listener);
		} else {
			traverseThumbList(listener);
		}
	}

	private void traverseThumbList(ScanManageListener listener) {
		setListener(listener);
		for (int i = 0; i < thumbList.size() && getListener() != null; i++) {
			File node = new File(thumbList.get(i));
			getListener().onNodeScan(TrashHelper.TRASH_THUMBNAIL, node);
		}
	}

	public void scanEmpty(String path, ScanManageListener listener) {
		if (isTimeUp() || !isScanComplete()) {
			scanFullPath(path, listener);
		} else {
			traverseEmptyList(listener);
		}
	}

	private void traverseEmptyList(ScanManageListener listener) {
		setListener(listener);
		for (int i = 0; i < emptyList.size() && getListener() != null; i++) {
			File node = new File(emptyList.get(i));
			getListener().onNodeScan(TrashHelper.TRASH_EMPTY, node);
		}
	}

	public void scanLargeFile(String path, ScanManageListener listener) {
		if (isTimeUp() || !isScanComplete()) {
			scanFullPath(path, listener);
		} else {
			traverseLargeFileList(listener);
		}
	}

	private void traverseLargeFileList(ScanManageListener listener) {
		setListener(listener);
		for (int i = 0; i < largeFileList.size() && getListener() != null; i++) {
			File node = new File(largeFileList.get(i));
			getListener().onNodeScan(TrashHelper.TRASH_LARGEFILE, node);
		}
	}

	public void scanFullPath(String path, ScanManageListener listener) {
		clearCache();
		setListener(listener);

		scan = new Scan(context);
		scan.setListener(mScanListener);
		scan.bfs(path);

		BatteryHelper.setTimeUp(context, TIME_LIMIT, System.currentTimeMillis());
	}

	public void scanPath(String path, ScanManageListener listener) {
		setListener(listener);
		scan = new Scan(context);
		scan.setListener(mScanListener);
		scan.bfs(path);
	}

	public void cancel() {
		if (scan != null) {
			scan.setCanceled(true);
		}
		setListener(null);
	}

	public ScanManageListener getListener() {
		return listener;
	}

	public void setListener(ScanManageListener listener) {
		this.listener = listener;
	}

	public boolean onApkDeleted(String uri) {
		return apkList.remove(uri);
	}

	public boolean onTrashDeleted(String uri) {
		return trashList.remove(uri);
	}

	public boolean onThumbDeleted(String uri) {
		return thumbList.remove(uri);
	}

	public boolean onEmptyDeleted(String uri) {
		return emptyList.remove(uri);
	}

	private void clearCache() {
		trashList.clear();
		apkList.clear();
		thumbList.clear();
		emptyList.clear();
		largeFileList.clear();
	}

	public void clear() {
		clearCache();
		scan = null;
	}

	private boolean isTimeUp() {
		return BatteryHelper.isTimeUp(context, TIME_LIMIT, 2 * BatteryHelper.MINUTE);
	}

	public boolean isScanComplete() {
		if (scan != null) {
			return scan.isComplete();
		} else {
			return false;
		}
	}

	public long getTotalProgress() {
		long res = -1;
		if(scan != null) {
			res = scan.mUsedSize;
		}
		return res;
	}

	public long getCurrentProgress() {
		long res = -1;
		if(scan != null) {
			res = scan.mScanSize;
		}
		return res;
	}

	public Context getContext() {
		return context;
	}

	//16 JELLY_BEAN Android 4.1.
	public static boolean isSupportMediaStore() {
		boolean res = Build.VERSION.SDK_INT >= 16;
		return res;
	}
}
